#pragma once

#include <stdlib.h>
#define _USE_MATH_DEFINES
#include <math.h>

#include "Basic2DCanvas.h"

#define getrandom(min, max) ((rand()%(int)(((max) + 1)-(min)))+ (min))

class LTree
{
	Basic2DCanvas canvas;
	//string production rules
	const char *atom;                     //starting string
	const char *Fstr;   //F production rule
	const char *Xstr;             //X production rule
	const char *Ystr;                       //Y production rule
	static const int angle = 18;                         //turn angle
	static const int length = 27;                          //forward length
	//min and max extremes for the window size
	float xmin, xmax, ymin, ymax;
	int list;	// display list
	const double scaling;
	struct {double x,y,z;} shift;

public:
	LTree(double scaling, double tx, double ty, double tz);
	~LTree(void);
	void draw() const;
	void drawLeaf() const;
	//Draw L-System from String--------------------------------
	void produceString(const char *st,int order, int draw)
	{
		float sx, sy, sa;
		glLineWidth(order);

		while(*st != '\0')		// scan through each character
		{
			switch(*st)
			{
			case '[': 
				canvas.saveTurtle();
				if (draw)
					canvas.thickness -= 1.0;
				break;
			case ']':
				canvas.restoreTurtle();
				if (draw)
					canvas.thickness += 1.0;
				break;	
			case '+': canvas.turn(-angle*getrandom(15,22)/22.0); break;	// right turn
			case '-': canvas.turn(angle*getrandom(15,22)/22.0); break;  // left turn
			case 'F': if(order > 0) 
						  produceString(Fstr, order - 1, draw);
					  else
					  {
						  canvas.forward(length, draw);
						  if(!draw)
						  {
							  if(canvas.getCP().x < xmin)
								  xmin = canvas.getCP().x;
							  if(canvas.getCP().x > xmax)
								  xmax = canvas.getCP().x;
							  if(canvas.getCP().y < ymin)
								  ymin = canvas.getCP().y;
							  if(canvas.getCP().y > ymax)
								  ymax = canvas.getCP().y;
						  }
					  }
					  break;
			case 'L': 
				if ((order <= 0) && draw) {
					if (canvas.getCP().y > ymax/5) {
						int r = (int) rand()%70 + (50*canvas.getCP().y)/ymax;
						if (r>80)
							drawLeaf();
					}
				}
				break;
			case 'X': if(order > 0)
						  produceString(Xstr, order - 1, draw); break;
			case 'Y': if(order > 0)
						  produceString(Ystr, order - 1, draw); break;
			}
			st++;
		}
	}

	int createTreeList(void);
};

